package com.jiang.books.domain;

import org.hibernate.annotations.Type;
import org.hibernate.envers.Audited;
import org.hibernate.envers.NotAudited;
import org.joda.time.DateTime;
import org.springframework.data.domain.Auditable;
import static javax.persistence.GenerationType.SEQUENCE;

import javax.persistence.*;

import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "jiang_user")
@NamedQueries({
        @NamedQuery(name="User.findAll",
                query="select c from User c"),
        @NamedQuery(name="User.findById",
                query="select distinct c from User c where c.id = :id"),
        @NamedQuery(name="User.findByGroupId",
        query="select c from User c where c.userGroup = :userGroup")
})
@SqlResultSetMapping(
    name="UserResult",
    entities=@EntityResult(entityClass=User.class))

@Audited
public class User implements Serializable, Auditable<String, Long> {

    private static final long serialVersionUID = 1L;

    private Long id;
    private String userLogin;
    private String userPassword;
    private String userName;
    private UserGroup userGroup;
    private Date birthday;
    private String email;
    
    private Set<Book> books = new HashSet<Book>();

    // Audit fields
    private String createdBy;
    private DateTime createdDate;
    private String lastModifiedBy;
    private DateTime lastModifiedDate;

    public User () {
    }

    public User (String userLogin, String userPassword, String userName, UserGroup userGroup) {
        this.userLogin = userLogin;
        this.userPassword = userPassword;
        this.userName = userName;
        this.userGroup = userGroup;
    }

    @Id
    @GeneratedValue(strategy = SEQUENCE, generator="JIANG_SEQ")
    @SequenceGenerator(name="JIANG_SEQ", sequenceName="jiang_id_sequence")
    @Column(name = "ID", unique = true, nullable = false)
    public Long getId() {
        return id;
    }

    @Column(name = "user_login")
    public String getUserLogin() {
        return userLogin;
    }

    @Column(name = "user_password")
    public String getUserPassword() {
        return userPassword;
    }

    @Column(name = "user_name")
    public String getUserName() {
        return userName;
    }

    @ManyToOne
    @JoinColumn(name = "user_group_id")
    public UserGroup getUserGroup() {
        return userGroup;
    }

    @Column(name = "birthday")
    public Date getBirthday() {
        return birthday;
    }

    @Column(name = "email")
    public String getEmail() {
        return email;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setUserLogin(String userLogin) {
        this.userLogin = userLogin;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setUserGroup(UserGroup userGroup) {
        this.userGroup = userGroup;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public void setEmail(String email) {
        this.email = email;
    }
    
    @ManyToMany
    @NotAudited
    @JoinTable(name = "jiang_user_books",
            joinColumns = @JoinColumn(name = "USER_ID"),
            inverseJoinColumns = @JoinColumn(name = "BOOK_ID"))
    public Set<Book> getBooks() {
        return this.books;
    }

    public void setBooks(Set<Book> books) {
        this.books = books;
    }

	public void addBook(Book book, String userComment, int mark) {
        UserBook ub = new UserBook(this, book);
        
        ub.setUserComment(userComment);
        ub.setMark(mark);
        ub.setAddDate(new Date());

		getBooks().add(book);
	}

	public void removeBook(Book book) {
		getBooks().remove(book);
	}

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userLogin='" + userLogin + '\'' +
                ", userPassword='" + userPassword + '\'' +
                ", userName='" + userName + '\'' +
                ", userGroup=" + userGroup.getGroupName() +
                ", birthday=" + birthday +
                ", email='" + email + '\'' +
                '}';
    }

    @Column(name="CREATED_BY")
    public String getCreatedBy() {
        return createdBy;
    }

    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    @Column(name="CREATED_DATE")
    @Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
    public DateTime getCreatedDate() {
        return createdDate;
    }

    public void setCreatedDate(DateTime createdDate) {
        this.createdDate = createdDate;
    }

    @Column(name="LAST_MODIFIED_BY")
    public String getLastModifiedBy() {
        return lastModifiedBy;
    }

    public void setLastModifiedBy(String lastModifiedBy) {
        this.lastModifiedBy = lastModifiedBy;
    }

    @Column(name="LAST_MODIFIED_DATE")
    @Type(type="org.joda.time.contrib.hibernate.PersistentDateTime")
    public DateTime getLastModifiedDate() {
        return lastModifiedDate;
    }

    public void setLastModifiedDate(DateTime lastModifiedDate) {
        this.lastModifiedDate = lastModifiedDate;
    }

    @Transient
    public boolean isNew() {
        if (id == null) {
            return true;
        } else {
            return false;
        }
    }
}